原文連結:Creating Instances of a Class
在class外使用靜態屬性時,難以單從屬性名稱鑑別該屬性來自哪個類別,所以使用=>
來連接類別名稱與屬性名(中間無空格),並指派該屬性的值。
* <class_name>=><static>
lcl_connection=>conn_counter =1234. "為類別中的常數賦值"
變數宣告要額外使用參照變數(reference variable),參照變數是一種特殊類別的變數,用來創建、定位並管理物件,並且該物件會指向該實體在記憶體的位置。在TYPE REF
後方接要引用的類別。
初始值會用NULL表示,代表尚未被指向至特定位置。
* DATA <reference_variable> TYPE REF TO<class_name>.
DATA connection TYPE REF TO lcl_connection. "參照變數"
有了先前的參照變數宣告,使用NEW #( )
接著來建立新實體,NEW #( )
可以透過宣告的位置知道要從哪個類別和屬性建立實體。#()
代表按照=
左側的參照變數建立實體。在進階用法中,則可以直接替換成指定的類別。
DATA connection TYPE REF TO lcl_connection. "參照變數"
connection = NEW #( ). "根據參照變數建立實體"
注意,無論是建立常數或變數,該類別的所有屬性都會被載入在記憶體中,包含了所有常數。
然而,常數僅會占用一筆記憶體空間,而非存在所有實體中,畢竟常數無法更改,也就不用每個類別實體都個別存一份值了。這也是常數不用先指定參照類別的原因。
想要指派變數中特定屬性的值,除了需要先建立參照變數外,還要透過->
來指定屬性。不像大多數的語言,ABAP在指派屬性給常數跟變數時的符號是不同的(常數為=>
,變數為->
)。
DATA connection TYPE REF TO lcl_connection.
connection = NEW#().
connection->carrier_id = 'LH'. "選擇屬性並賦值"
connection->connection_id = '0400'. "選擇屬性並賦值"
如2.所述,同一類別的不同實體有各自獨立的位址,變數值也會各自存放在不同地方,但他們的常數屬性都是共用同一個地方的值。
注意,在ABAP中,如果對剛建好的參照變數(未建立實體)直接賦值另一個參照變數,由於賦值的只是位址資訊而已,兩個值所指向的會是同一個記憶體位置,變更參數A的同時也會一起改到參數B。
DATA connectionA TYPE REF TO lcl_connection.
DATA connectionB TYPE REF TO lcl_connection.
connectionA = NEW #( ).
connectionB = connectionA. "此時A與B皆指向同一個記憶體位址,故任一參數值被更改,另一個的值也會一起被變更"
雖然可以直接重複建立同一變數的新實體,但此時會在新的記憶體空間直接新建一個,並且斷開與舊實體的指向。
DATA connection TYPE REF TO lcl_connection.
connection = NEW#(). "建立舊實體"
...
connection = NEW#(). "建立新實體,舊實體指向被斷開"
但是時間一久,那些被斷開且再也無法指向的舊實體將持續占用記憶體的空間。為了避免記憶體被這些失去指向的舊實體塞爆,在ABAP執行生命週期裡,有個垃圾收集器專門定期清除這些失去指向的實體。
覆寫及使用CLEAR使物件失去參照時,都會觸發收集器。當程式結束執行時,也會觸發這個收集器來清空記憶體裡存的所有變數。
ABAP裡有一種可以維持物件指向的方式,就是把參照變數存在Internal Table裡面。
在下面範例中,由於有事先將connection存入Internal Table裡面,即使對connection進行CLEAR,仍是可以透過Internal Table找到原先已存入的connection。
DATA connection TYPE REF TO lcl_connection. "建立參照變數"
DATA connections TYPE TABLE OF REF TO lcl_connection. "建立Internal Table"
connection = NEW #( ). "建立實體"
APPEND connection TO connections." 把實體存入Internal Table"
CLEAR connection. "清除實體指向,但仍可在Internal Table中找到該實體"
看完是否有對ABAP變數實體的建立方式及背後邏輯更了解?接著就要進入函式宣告囉!